<!DOCTYPE html>
<html>
<body>

<canvas id="physicsCanvas" width="550" height="300" style="border:1px solid #d3d3d3;"></canvas>

<script>
    const canvas = document.getElementById("physicsCanvas");
    const ctx = canvas.getContext("2d");

    // Helper function to draw an arrow
    function drawArrow(ctx, fromx, fromy, tox, toy, headlen = 10) {
        const dx = tox - fromx;
        const dy = toy - fromy;
        const angle = Math.atan2(dy, dx);
        ctx.beginPath();
        ctx.moveTo(fromx, fromy);
        ctx.lineTo(tox, toy);
        ctx.stroke();
        ctx.beginPath();
        ctx.moveTo(tox, toy);
        ctx.lineTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6));
        ctx.moveTo(tox, toy);
        ctx.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6));
        ctx.stroke();
    }

    // Helper function to draw dimension lines like 'a' and 'b'
    function drawDimensionLine(ctx, x, y_base, y_top, label) {
        ctx.save();
        ctx.lineWidth = 1.5;

        // Vertical line
        ctx.beginPath();
        ctx.moveTo(x, y_base);
        ctx.lineTo(x, y_top);

        // T-stops
        ctx.moveTo(x - 4, y_base);
        ctx.lineTo(x + 4, y_base);
        ctx.moveTo(x - 4, y_top);
        ctx.lineTo(x + 4, y_top);
        ctx.stroke();
        
        // Arrowhead at the top
        const headlen = 8;
        const angle = -Math.PI / 2; // Pointing up
        ctx.beginPath();
        ctx.moveTo(x, y_top);
        ctx.lineTo(x - headlen * Math.cos(angle - Math.PI / 6), y_top - headlen * Math.sin(angle - Math.PI / 6));
        ctx.moveTo(x, y_top);
        ctx.lineTo(x - headlen * Math.cos(angle + Math.PI / 6), y_top - headlen * Math.sin(angle + Math.PI / 6));
        ctx.stroke();
        
        // Label
        ctx.font = "italic 20px Times New Roman";
        ctx.textAlign = "center";
        ctx.fillText(label, x - 15, (y_base + y_top) / 2 + 7);
        ctx.restore();
    }

    // Parameters for the drawing
    const cy = 150; // Center y-coordinate
    const cx_front = 150; // x-coordinate of the front face center
    const cx_back = 450;  // x-coordinate of the back face center
    const rx = 30;  // ellipse semi-major axis (perspective)
    const ry_a = 40; // inner radius (ellipse semi-minor axis)
    const ry_b = 80; // outer radius (ellipse semi-minor axis)

    // --- Start Drawing ---
    
    // 1. Draw z-axis and dimension lines (background elements)
    ctx.lineWidth = 2;
    ctx.strokeStyle = "black";
    ctx.fillStyle = "black";

    // z-axis
    ctx.beginPath();
    ctx.moveTo(20, cy);
    ctx.lineTo(520, cy);
    ctx.stroke();
    drawArrow(ctx, 510, cy, 520, cy, 8);
    ctx.font = "italic 20px Times New Roman";
    ctx.textAlign = "left";
    ctx.fillText("z", 525, cy + 8);

    // Dimension lines 'a' and 'b'
    drawDimensionLine(ctx, 60, cy, cy - ry_b, "b");
    drawDimensionLine(ctx, 90, cy, cy - ry_a, "a");

    // 2. Draw the hollow cylinder
    // Fill the gray conductor material first
    ctx.fillStyle = "#D3D3D3";
    // Rectangular part
    ctx.fillRect(cx_front, cy - ry_b, cx_back - cx_front, 2 * ry_b);
    // Front face elliptical part
    ctx.beginPath();
    ctx.ellipse(cx_front, cy, rx, ry_b, 0, 0, 2 * Math.PI);
    ctx.fill();

    // Carve out the white inner hole
    ctx.fillStyle = "white";
    // Rectangular part
    ctx.fillRect(cx_front, cy - ry_a, cx_back - cx_front, 2 * ry_a);
    // Front face elliptical part
    ctx.beginPath();
    ctx.ellipse(cx_front, cy, rx, ry_a, 0, 0, 2 * Math.PI);
    ctx.fill();

    // Draw all black outlines on top for a crisp look
    ctx.lineWidth = 2;
    // Outer boundary lines
    ctx.beginPath();
    ctx.moveTo(cx_front, cy - ry_b);
    ctx.lineTo(cx_back, cy - ry_b);
    ctx.moveTo(cx_front, cy + ry_b);
    ctx.lineTo(cx_back, cy + ry_b);
    ctx.stroke();
    // Inner boundary lines
    ctx.beginPath();
    ctx.moveTo(cx_front, cy - ry_a);
    ctx.lineTo(cx_back, cy - ry_a);
    ctx.moveTo(cx_front, cy + ry_a);
    ctx.lineTo(cx_back, cy + ry_a);
    ctx.stroke();
    // Front face outlines
    ctx.beginPath();
    ctx.ellipse(cx_front, cy, rx, ry_b, 0, 0, 2 * Math.PI);
    ctx.stroke();
    ctx.beginPath();
    ctx.ellipse(cx_front, cy, rx, ry_a, 0, 0, 2 * Math.PI);
    ctx.stroke();

    // Draw dashed lines for the back face
    ctx.setLineDash([5, 5]);
    // Outer back ellipse
    ctx.beginPath();
    ctx.ellipse(cx_back, cy, rx, ry_b, 0, Math.PI / 2, 3 * Math.PI / 2);
    ctx.stroke();
    // Inner back ellipse
    ctx.beginPath();
    ctx.ellipse(cx_back, cy, rx, ry_a, 0, Math.PI / 2, 3 * Math.PI / 2);
    ctx.stroke();
    ctx.setLineDash([]); // Reset to solid lines

    // 3. Draw current arrows and labels
    ctx.fillStyle = "black";
    ctx.textAlign = "center";
    ctx.font = "20px Times New Roman";

    // Current I (return current)
    const y_I = cy - ry_b - 15;
    drawArrow(ctx, 320, y_I, 240, y_I);
    ctx.fillText("I", 280, y_I - 8);

    // Current I(r) (forward current)
    const y_Ir = cy - (ry_a + ry_b) / 2;
    drawArrow(ctx, 240, y_Ir, 340, y_Ir);
    ctx.fillText("I(r)", 290, y_Ir - 8);

</script>

</body>
</html>